#include "gui/TextBox.h"

#include "utilities/Rectangle.h"

#define dbg(a) std::cout << a << std::endl

namespace gui
{
	TextBox::TextBox() : keyboardImage( NULL ), keyboardImageShift( NULL ), font( NULL )
	{
	}

	TextBox::TextBox( const gdn::Vector2f& thePos, const std::string& theDefaultText, unsigned int theMaxLength,
			          gdn::Image& theKeyboardImage, gdn::Image& theKeyboardImageShift, gdn::Font& theFont, const gdn::Color& theTextColor, unsigned int theCharSize,
			          const gdn::Vector2f& theTextPos, const CharacterMap& theCharacters, const CharacterMap& theCharactersShift )
	   : pos( thePos ), defaultText( theDefaultText ), text( defaultText ), maxLength( theMaxLength ), shift( true ),
	     keyboardImage( &theKeyboardImage ), keyboardImageShift( &theKeyboardImageShift ), font( &theFont ), textColor( theTextColor ), charSize( theCharSize ),
	     textPos( theTextPos ), characters( theCharacters ), charactersShift( theCharactersShift )
	{
		keyboard.SetPosition( pos );
		keyboard.SetImage( *keyboardImageShift );

		SetText( text );
		textDisplay.SetFont( *font );
		textDisplay.SetColor( textColor );
		textDisplay.SetCharacterSize( charSize );
		textDisplay.SetPosition( pos.x + textPos.x, pos.y + textPos.y );
	}

	int TextBox::Process( const gdn::Event& event )
	{
		if ( event.type == gdn::Event::MouseButtonPressed )
		{
			if ( event.mouseButton == gdn::Mouse::Left )
			{
				if ( !shift )
				{
					return AddCorrespondingCharacter( characters, mousePos );
				}
				else
				{
					return AddCorrespondingCharacter( charactersShift, mousePos );
				}
			}
		}
		else if ( event.type == gdn::Event::MouseMoved )
		{
			mousePos.x = event.x;
			mousePos.y = event.y;
		}

		return 0;
	}

	void TextBox::Draw( gdn::Window& window )
	{
		window.Draw( keyboard );
		window.Draw( textDisplay );
	}

	void TextBox::Draw( gdn::RenderImage& renderImage )
	{
		renderImage.Draw( keyboard );
		renderImage.Draw( textDisplay );
	}

	std::string TextBox::GetText() const
	{
		return text;
	}

	void TextBox::SetText( const std::string& theText )
	{
		text = theText.substr( 0, maxLength );
		textDisplay.SetString( text );
	}

	void TextBox::AppendText( const std::string& theText )
	{
		text = ( text + theText ).substr( 0, maxLength );
		textDisplay.SetString( text );
	}

	void TextBox::DeleteEndCharacter()
	{
		text = text.substr( 0, text.length() - 1 );
		textDisplay.SetString( text );
	}

	bool TextBox::AddCorrespondingCharacter( const CharacterMap& characterMap, gdn::Vector2f mousePos )
	{
		for ( size_t i = 0; i < characterMap.size(); ++i )
		{
			gdn::Rectanglef keyPos = characterMap[ i ].first;
			keyPos.x += pos.x;
			keyPos.y += pos.y;

			if ( util::RectangleContainsPoint< float >( keyPos, mousePos ) )
			{
				if ( characterMap[ i ].second == "DEL" )
				{
					DeleteEndCharacter();
				}
				else if ( characterMap[ i ].second == "SHIFT" )
				{
					ToggleShift();
					return false;
				}
				else if ( characterMap[ i ].second == "ENTER" )
				{
					return true;
				}
				else
				{
					AppendText( characterMap[ i ].second );
					if ( shift )
					{
						ToggleShift();
					}
				}
			}
		}

		return false;
	}

	void TextBox::ToggleShift()
	{
		shift = !shift;
		if ( !shift )
		{
			keyboard.SetImage( *keyboardImage );
		}
		else
		{
			keyboard.SetImage( *keyboardImageShift );
		}
	}
}

